﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ApiData.Common
{
    public static class TimeHelper
    {
        /// <summary>
        /// 获取的时间类型
        /// </summary>
        public enum TimeType
        {
            /// <summary>
            /// 星期
            /// </summary>
            Week,
            /// <summary>
            /// 月
            /// </summary>
            Month,
            /// <summary>
            /// 季度
            /// </summary>
            Season,
            /// <summary>
            /// 年
            /// </summary>
            Year
        }

        /// <summary>
        /// 获取本周/本月/本季度/今年开始时间
        /// </summary>
        /// <param name="timeType">类型枚举</param>
        /// <param name="time">某个时间</param>
        /// <returns></returns>
        public static DateTime? GetTimeStartByType(TimeType timeType, DateTime time)
        {
            DateTime? resultTime;
            switch (timeType)
            {
                case TimeType.Week:
                    resultTime = time.AddDays(-(int)time.DayOfWeek + 1);
                    break;
                case TimeType.Month:
                    resultTime = time.AddDays(-time.Day + 1);
                    break;
                case TimeType.Season:
                    var _time = time.AddMonths(0 - ((time.Month - 1) % 3));
                    resultTime = _time.AddDays(-_time.Day + 1);
                    break;
                case TimeType.Year:
                    resultTime = time.AddDays(-time.DayOfYear + 1);
                    break;
                default:
                    resultTime = null;
                    break;
            }
            if (resultTime.HasValue)
            {
                resultTime = new DateTime(resultTime.Value.Year, resultTime.Value.Month, resultTime.Value.Day, 0, 0, 0, 0);
            }
            return resultTime;
        }

        /// <summary>
        /// 获取本周/本月/本季度/今年结束时间
        /// </summary>
        /// <param name="timeType">类型枚举</param>
        /// <param name="time">某个时间</param>
        /// <returns></returns>
        public static DateTime? GetTimeEndByType(TimeType timeType, DateTime time)
        {
            DateTime? resultTime;
            switch (timeType)
            {
                case TimeType.Week:
                    resultTime = time.AddDays(7 - (int)time.DayOfWeek);
                    break;
                case TimeType.Month:
                    resultTime = time.AddMonths(1).AddDays(-time.AddMonths(1).Day + 1).AddDays(-1);
                    break;
                case TimeType.Season:
                    var _time = time.AddMonths((3 - ((time.Month - 1) % 3) - 1));
                    resultTime = _time.AddMonths(1).AddDays(-_time.AddMonths(1).Day + 1).AddDays(-1);
                    break;
                case TimeType.Year:
                    var time2 = time.AddYears(1);
                    resultTime = time2.AddDays(-time2.DayOfYear);
                    break;
                default:
                    resultTime = null;
                    break;
            }
            if (resultTime.HasValue)
            {
                resultTime = new DateTime(resultTime.Value.Year, resultTime.Value.Month, resultTime.Value.Day, 23, 59, 59, 999);
            }
            return resultTime;
        }

        /// <summary>
        /// 获取上周/上月/上季度/去年开始时间
        /// </summary>
        /// <param name="timeType">类型枚举</param>
        /// <param name="time">某个时间</param>
        /// <returns></returns>
        public static DateTime? GetBeforeTimeStartByType(TimeType timeType, DateTime time)
        {
            DateTime? resultTime;
            switch (timeType)
            {
                case TimeType.Week:
                    time = time.AddDays(-7);
                    resultTime = GetTimeStartByType(timeType, time);
                    break;
                case TimeType.Month:
                    time = time.AddMonths(-1);
                    resultTime = GetTimeStartByType(timeType, time);
                    break;
                case TimeType.Season:
                    time = time.AddMonths(-3);
                    resultTime = GetTimeStartByType(timeType, time);
                    break;
                case TimeType.Year:
                    time = time.AddYears(-1);
                    resultTime = GetTimeStartByType(timeType, time);
                    break;
                default:
                    resultTime = null;
                    break;
            }
            return resultTime;
        }

        /// <summary>
        /// 获取上周/上月/上季度/去年结束时间
        /// </summary>
        /// <param name="timeType">类型枚举</param>
        /// <param name="time">某个时间</param>
        /// <returns></returns>
        public static DateTime? GetBeforeTimeEndByType(TimeType timeType, DateTime time)
        {
            DateTime? resultTime;
            switch (timeType)
            {
                case TimeType.Week:
                    time = time.AddDays(-7);
                    resultTime = GetTimeEndByType(timeType, time);
                    break;
                case TimeType.Month:
                    time = time.AddMonths(-1);
                    resultTime = GetTimeEndByType(timeType, time);
                    break;
                case TimeType.Season:
                    time = time.AddMonths(-3);
                    resultTime = GetTimeEndByType(timeType, time);
                    break;
                case TimeType.Year:
                    time = time.AddYears(-1);
                    resultTime = GetTimeEndByType(timeType, time);
                    break;
                default:
                    resultTime = null;
                    break;
            }
            return resultTime;
        }

        /// <summary>
        /// 获取下周/下月/下季度/明年开始时间
        /// </summary>
        /// <param name="timeType">类型枚举</param>
        /// <param name="time">某个时间</param>
        /// <returns></returns>
        public static DateTime? GetAfterTimeStartByType(TimeType timeType, DateTime time)
        {
            DateTime? resultTime;
            switch (timeType)
            {
                case TimeType.Week:
                    time = time.AddDays(7);
                    resultTime = GetTimeStartByType(timeType, time);
                    break;
                case TimeType.Month:
                    time = time.AddMonths(1);
                    resultTime = GetTimeStartByType(timeType, time);
                    break;
                case TimeType.Season:
                    time = time.AddMonths(3);
                    resultTime = GetTimeStartByType(timeType, time);
                    break;
                case TimeType.Year:
                    time = time.AddYears(1);
                    resultTime = GetTimeStartByType(timeType, time);
                    break;
                default:
                    resultTime = null;
                    break;
            }
            return resultTime;
        }

        /// <summary>
        /// 获取下周/下月/下季度/明年结束时间
        /// </summary>
        /// <param name="timeType">类型枚举</param>
        /// <param name="time">某个时间</param>
        /// <returns></returns>
        public static DateTime? GetAfterTimeEndByType(TimeType timeType, DateTime time)
        {
            DateTime? resultTime;
            switch (timeType)
            {
                case TimeType.Week:
                    time = time.AddDays(7);
                    resultTime = GetTimeEndByType(timeType, time);
                    break;
                case TimeType.Month:
                    time = time.AddMonths(1);
                    resultTime = GetTimeEndByType(timeType, time);
                    break;
                case TimeType.Season:
                    time = time.AddMonths(3);
                    resultTime = GetTimeEndByType(timeType, time);
                    break;
                case TimeType.Year:
                    time = time.AddYears(1);
                    resultTime = GetTimeEndByType(timeType, time);
                    break;
                default:
                    resultTime = null;
                    break;
            }
            return resultTime;
        }
    }
}